import { PREVIEW } from "cc/env";

// 日期格式化结构信息
interface DateFormat {
    [propName: string]: any;
}

/**
 * 时间梯度枚举；
 * （提前计算好每个梯度，提高运算效率）
 */
export enum TimeStair {
    /** 毫秒 */
    ms = 1,
    /** 秒 */
    s = 1000,
    /** 分 */
    m = 60 * 1000,
    /** 小时 */
    h = 3600 * 1000,
    /** 天 */
    d = 24 * 3600 * 1000,
}

/** 格式化时间、日期、计时器等字符串显示样式 */
export default class FormatTime {

    /**
     * 格式化日期字符串；
     * @yields 连接符可自定义，空格随意；
     * @yields 年月日等特殊字符定义如下：
     * @var YYYY | YY -- 4 or 2位 年
     * @var MM | M -- 2 or 不限位 月
     * @var DD | D -- 2 or 不限位 日
     * @var HH | H -- 2 or 不限位 时
     * @var mm | m -- 2 or 不限位 分
     * @var ss | s -- 2 or 不限位 秒
     * @param time 时间戳(ms)，不传则取用当前本地时间戳
     * @param format 格式化样式, 默认格式"YYYY-MM-DD HH:mm:ss"
     * @returns
     */
    static date(time: string | number | null, format = "YYYY-MM-DD HH:mm:ss"): string {
        const date: Date = !time ? new Date() : new Date(time);
        const obj: DateFormat = {
            YYYY: date.getFullYear(),
            MM: ("0" + (date.getMonth() + 1)).slice(-2),
            DD: ("0" + date.getDate()).slice(-2),
            HH: ("0" + date.getHours()).slice(-2),
            mm: ("0" + date.getMinutes()).slice(-2),
            ss: ("0" + date.getSeconds()).slice(-2),
            YY: ("" + date.getFullYear()).slice(-2),
            M: date.getMonth() + 1,
            D: date.getDate(),
            H: date.getHours(),
            m: date.getMinutes(),
            s: date.getSeconds(),
        };

        Object.keys(obj).forEach((key: string) => {
            format = format.replace(key, obj[key]);
        });
        return format;
    }

    /**
     * 格式化倒计时格式
     * @var HH | H -- 2 or 不限位 时
     * @var mm | m -- 2 or 不限位 分
     * @var ss | s -- 2 or 不限位 秒
     * @argument 'H:mm:ss' 时分秒格式（超24小时叠加，建议使用'H'，防止超过3位数被截断）
     * @argument 'm:ss' 分秒格式（超60分钟叠加，建议使用'm'，防止超过3位数被截断）
     * @argument 'ss' 秒格式（超60秒叠加，建议使用's'，防止超过3位数被截断）
     * @param leftMSec 剩余毫秒数
     * @param format 格式化样式，默认格式'HH:mm:ss'
     */
    static timer(leftMSec: number, format: string = "HH:mm:ss"): string {
        // 3：'时分秒'样式；2:'分秒'样式；1：'秒'样式
        const style: number = format.indexOf("H") == 0 ? 3 : format.indexOf("m") == 0 ? 2 : 1;

        // 格式化结构体
        let obj: DateFormat;
        if (style == 1) {
            // '秒'样式
            const sec: number = Math.floor(leftMSec / TimeStair.s);
            obj = {
                ss: sec < 10 ? ("0" + sec).slice(-2) : sec,
                s: sec,
            };
            Object.keys(obj).forEach((key: string) => {
                format = format.replace(key, obj[key]);
            });
        }
        else if (style == 2) {
            // '分秒'样式
            const min: number = Math.floor(leftMSec / TimeStair.m);
            const sec: number = Math.floor((leftMSec - min * TimeStair.m) / TimeStair.s);
            obj = {
                mm: min < 10 ? ("0" + min).slice(-2) : min,
                m: min,
                ss: sec < 10 ? ("0" + sec).slice(-2) : sec,
                s: sec,
            };
            Object.keys(obj).forEach((key: string) => {
                format = format.replace(key, obj[key]);
            });
        }
        else if (style == 3) {
            // '时分秒'样式
            const hou: number = Math.floor(leftMSec / TimeStair.h);
            const min: number = Math.floor((leftMSec - hou * TimeStair.h) / TimeStair.m);
            const sec: number = Math.floor((leftMSec - hou * TimeStair.h - min * TimeStair.m) / TimeStair.s);
            obj = {
                HH: hou < 10 ? ("0" + hou).slice(-2) : hou,
                H: hou,
                mm: min < 10 ? ("0" + min).slice(-2) : min,
                m: min,
                ss: sec < 10 ? ("0" + sec).slice(-2) : sec,
                s: sec,
            };
            Object.keys(obj).forEach((key: string) => {
                format = format.replace(key, obj[key]);
            });
        }

        return format;
    }

}
if (PREVIEW)
    globalThis.FormatTime = FormatTime;
